import echarts from "@/components/echarts/index";
import { deepClone } from "@/utils";
export const chartStyle = {
  width: "100%",
  height: "400px",
};
//图标 线或者柱状图的颜色
export const chartCfg = {
  line: {
    color: ["#c00000", "#ffc000"], //默认颜色
    width: 2,
    highlight: "#ffc000", //自己设置的 ，echart api里面没有
  },
  bar: {
    barWidth: "", //barWidth 柱条的宽度，不设时自适应。可以是绝对值例如 40 或者百分数例如 '60%'。百分数基于自动计算出的每一类目的宽度。
    color: ["#c00000"], //对应 itemStyle:{color:""}
    highlight: "#ffc000", //高亮 自己设置的，api里面没有
  },
};
export function setDefaultChartCfg() {
  let newChartCfg = JSON.parse(localStorage.getItem("chartCfg") || "{}");
  let { line, bar } = newChartCfg;
  if (line) {
    chartCfg.line.color = line.data.map((item) => item.lineColor);
    chartCfg.line.width = line.lineWidth;
    chartCfg.line.highlight = line.highlight;
  } else {
    chartCfg.line = {
      color: ["#c00000", "#ffc000"], //默认颜色
      width: 2,
      highlight: "#ffc000", //自己设置的 ，echart api里面没有
    };
  }
  if (bar) {
    chartCfg.bar.color = bar.data.map((item) => item.barColor);
    chartCfg.bar.barWidth = bar.isAdaptation ? "" : bar.barWidth;
    chartCfg.bar.highlight = bar.highlight;
  } else {
    chartCfg.bar = {
      barWidth: "", //barWidth 柱条的宽度，不设时自适应。可以是绝对值例如 40 或者百分数例如 '60%'。百分数基于自动计算出的每一类目的宽度。
      color: ["#c00000"], //对应 itemStyle:{color:""}
      highlight: "#ffc000", //高亮 自己设置的，api里面没有
    };
  }
}

let copyChartCfg = []; //存储默认颜色的值(由于series 某个系列会有高亮的，为了保证默认的系列是按照配置的顺序获取颜色值)
//获取配置的颜色 (取一个，删除一个，每次取的都是第一个)
function getChartColor(type) {
  return copyChartCfg[type]["color"].length === 0 ? "" : copyChartCfg[type]["color"].shift();
}
const saveImage = (myChart, data) => {
  let opts = {
    type: "png", // 导出的格式，可选 png, jpeg
    pixelRatio: 1, // 导出的图片分辨率比例，默认为 1。
    backgroundColor: "#fff", // 导出的图片背景色，默认使用 option 里的 backgroundColor
    // 忽略组件的列表，例如要忽略 toolbox 就是 ['toolbox'],一般也忽略了'toolbox'这栏就够了
    // excludeComponents: Array.<string>
  };
  //动画加载完之后获取base64数据
  // 监听动画完成事件
  myChart.on("finished", function () {
    console.log("ECharts动画完成！");
    let resBase64 = myChart.getDataURL(opts); //拿到base64 地址，就好下载了。
    // console.log("this.resBase64", resBase64);
    data.base64 = resBase64;
    data.isConfig = true;
    // 在这里执行动画完成后的代码
  });
};
//图表--柱状图
export const chartBarSW = class ChartBarSW {
  constructor({ id, data }) {
    //类似于vue的$nextTick 等dom元素渲染元之后
    setTimeout(() => {
      this.data = data;
      copyChartCfg = deepClone(chartCfg);

      this.type = "bar";
      this.barCfg = chartCfg[this.type];
      this.highlight = this.barCfg.highlight;
      console.log("---------", this.highlight);

      this.myChart?.clear();
      let chartDom = id instanceof HTMLElement ? id : document.getElementById(id);
      chartDom.style.width = chartStyle.width;
      chartDom.style.height = chartStyle.height;
      this.myChart = echarts.init(chartDom);
      this.initData();
      this.initOption();
    });
  }
  initData() {
    let { title, x_list, series, highlight } = this.data;
    this.title = title;
    this.x_list = x_list;
    this.legend = null;
    series.forEach((item) => {
      let data = item.data;
      item["barWidth"] = this.barCfg.barWidth;
      let color = item.type === "平均值" ? this.highlight : getChartColor(this.type);
      data.forEach((yData, index, arr) => {
        if (highlight && highlight.includes(x_list[index])) {
          //因为从LLM组直接渲染到界面的时候我已经解析了，现在是块编辑引擎在渲染的时候就不需要在解析了(todo:后来：但是由于高亮色配置化（配置管理-图表配置）之后，之前保存过的不能实时更新过来高亮的颜色)
          // if (yData.itemStyle) return;
          // arr[index] = {
          //   value: yData,
          //   itemStyle: { color: this.highlight },
          // };
          //最新逻辑（配置高亮色之后，也能实时同步过来高亮色）
          if (yData.itemStyle) {
            //之前已经设置过高亮色的 直接赋值就可以了（如果高亮不同的话，就直接替换了）
            yData.itemStyle.color = this.highlight;
          } else {
            //没有设置高亮色的情况
            arr[index] = {
              value: yData,
              itemStyle: { color: this.highlight },
            };
          }
        }
      });
      item["type"] = "bar";
      item["itemStyle"] = { color };
    });
    this.grid = { top: 20, left: 0, right: 0, bottom: 10, containLabel: true };
    //有两条线的 展示图例
    if (series.length > 1) {
      this.legend = { top: 40 };
      this.grid.top = 60;
    }
    this.series = series;
  }
  initOption() {
    this.option = {
      // title: {
      //   left: "center",
      //   text: this.title,
      // },
      legend: this.legend,
      grid: this.grid,
      tooltip: { show: true },
      xAxis: {
        type: "category",
        data: this.x_list,
        axisLabel: {
          formatter: function (value) {
            return value.split("").join("\n");
          },
        },
        axisTick: {
          show: false, //刻度线
        },
      },
      yAxis: {
        type: "value",
        axisLine: { show: true },
        // interval: 2, //强制设置坐标轴分割间隔。
        splitLine: {
          show: false,
        },
        axisLabel: {
          formatter: function (value) {
            return value.toFixed(2); // 保留两位小数
          },
        },
        axisTick: {
          show: true,
          inside: true,
        },
      },
      series: this.series,
    };
    this.myChart.setOption(this.option);
    saveImage(this.myChart, this.data);
  }
};
//图表--线性图
export const chartLineSW = class ChartLineSW {
  constructor({ id, data }) {
    //类似于vue的$nextTick 等dom元素渲染元之后
    setTimeout(() => {
      this.data = data;
      copyChartCfg = deepClone(chartCfg);

      this.type = "line";
      this.lineCfg = chartCfg[this.type];
      this.highlight = this.lineCfg.highlight;

      this.myChart?.clear();
      // let chartDom = document.getElementById(id);
      let chartDom = id instanceof HTMLElement ? id : document.getElementById(id);
      chartDom.style.width = chartStyle.width;
      chartDom.style.height = chartStyle.height;
      this.myChart = echarts.init(chartDom);
      this.initData();
      this.initOption();
    });
  }
  initData() {
    let { title, x_list, series } = this.data;
    this.title = title;
    this.x_list = x_list;
    this.legend = null;
    series.forEach((item, index) => {
      let color = item.name === "平均值" ? this.highlight : getChartColor(this.type);
      item["type"] = "line";
      item["showSymbol"] = item.showSymbol || false;
      item["itemStyle"] = { color };
      item["lineStyle"]["width"] = this.lineCfg.width;
    });
    this.grid = { top: 20, left: 0, right: 0, bottom: 10, containLabel: true };
    //有两条线的 展示图例
    if (series.length > 1) {
      this.legend = { top: 40 };
      this.grid.top = 60;
    }
    this.series = series;
  }
  initOption() {
    this.option = {
      // title: { text: this.title },
      legend: this.legend,
      tooltip: {
        trigger: "axis",
      },
      grid: this.grid,
      xAxis: {
        type: "category",
        margin: 20,
        boundaryGap: true, //设置坐标轴两边留白
        data: this.x_list,
        axisLabel: {
          rotate: 60, // 旋转角度
        },
      },
      yAxis: {
        type: "value",
        axisLine: { show: true },
        splitLine: {
          show: false,
        },
        axisLabel: {
          formatter: function (value) {
            return value.toFixed(2); // 保留两位小数
          },
        },
        axisTick: {
          show: true,
          inside: true,
        },
      },
      series: this.series,
    };
    this.myChart.setOption(this.option);
    saveImage(this.myChart, this.data);
  }
};
//图表--柱状线性图
export const chartBarLineSW = class chartBarLineSW {
  constructor({ id, data }) {
    //类似于vue的$nextTick 等dom元素渲染元之后
    setTimeout(() => {
      this.data = data;
      copyChartCfg = deepClone(chartCfg);

      this.type = "line";
      this.lineCfg = chartCfg["line"];
      this.barCfg = chartCfg["bar"];
      this.lineHighlight = this.lineCfg.highlight;
      this.barHighlight = this.barCfg.highlight;

      this.myChart?.clear();
      let chartDom = id instanceof HTMLElement ? id : document.getElementById(id);
      chartDom.style.width = chartStyle.width;
      chartDom.style.height = chartStyle.height;
      this.myChart = echarts.init(chartDom);
      this.initData();
      this.initOption();
    });
  }
  initData() {
    let { title, x_list, series, highlight } = this.data;
    this.title = title;
    this.x_list = x_list;
    this.legend = null;
    this.yAxis = [
      {
        type: "value",
        axisLine: { show: true },
        // interval: 2, //强制设置坐标轴分割间隔。
        splitLine: {
          show: false,
        },
        axisLabel: {
          formatter: function (value) {
            return value.toFixed(2); // 保留两位小数
          },
        },
        axisTick: {
          show: true,
          inside: true,
        },
      },
      {
        type: "value",
        name: "yoy", //动态填充
        position: "right",
        axisLine: {
          show: true, //坐标轴线
        },
        axisTick: {
          //坐标轴刻度线
          show: true,
          inside: true,
        },
        //分割线
        splitLine: {
          show: false,
        },
        axisLabel: {
          formatter: function (value) {
            return value.toFixed(2); // 保留两位小数
          },
        },
      },
    ];

    series.forEach((item) => {
      if (disposeIncludes("chart::BarLine::SW", item.name)) {
        item["type"] = "line";
        item["itemStyle"] = { color: this.lineHighlight };
        this.yAxis[1].name = item.name;
        item["showSymbol"] = false;
        item["yAxisIndex"] = 1; //多个y轴的时候，这个一定要设置，不然显示不出来右侧的y轴坐标轴
        item["lineStyle"] = {
          width: this.lineCfg.width,
        };
      } else {
        item["type"] = "bar";
        this.yAxis[0].name = item.name;
        item["barWidth"] = this.barCfg.barWidth;
        item["itemStyle"] = { color: getChartColor("bar") };
      }
    });
    this.grid = { top: 20, left: 0, right: 30, bottom: 10, containLabel: true };
    //有两条线的 展示图例
    if (series.length > 1) {
      this.legend = { top: 40 };
      this.grid.top = 60;
    }
    this.series = series;
  }
  initOption() {
    this.option = {
      // title: {
      //   left: "center",
      //   text: this.title,
      // },
      legend: this.legend,
      grid: this.grid,
      tooltip: { show: true },
      xAxis: {
        type: "category",
        data: this.x_list,
        axisTick: {
          show: false, //刻度线
        },
      },
      yAxis: this.yAxis,
      series: this.series,
    };
    this.myChart.setOption(this.option);
    saveImage(this.myChart, this.data);
  }
};
// 判断是否包含某些字段
function disposeIncludes(type, name) {
  if (type === "chart::Bar::SW") {
  } else if (type === "chart::Line::SW") {
    return ["平均值"].some((item) => name.includes(item));
  } else if (type === "chart::BarLine::SW") {
    return ["同比", "YOY", "yoy"].some((item) => name.includes(item));
  }
}
// 处理设置数据
function setChartCfg(data, type) {
  chartCfg.line.color = [];
  chartCfg.bar.color = [];
  data.series.forEach((item) => {
    if (item.type == "line") {
      chartCfg.line.color.push(item.itemStyle.color);
      chartCfg.line.width = item.lineStyle.width;
      if (disposeIncludes(type, item.name)) chartCfg.line.highlight = item.itemStyle.color;
    } else if (item.type == "bar") {
      chartCfg.bar.color.push(item.itemStyle.color);
      chartCfg.bar.barWidth = item.barWidth;
      let newArr = item.data.filter((eve) => {
        return typeof eve === "object" && eve !== null;
      });
      chartCfg.bar.highlight = newArr[0]?.itemStyle.color;
    }
  });
}
//setting:true/false 决定是否是走的单独设置
export const chartRender = ({ id, data, setting }) => {
  let { type } = data;
  // isConfig 第一次画走默认值 保存数据走isConfig
  if (setting || data.data.isConfig) {
    setChartCfg(data.data, type);
  } else {
    setDefaultChartCfg();
  }
  if (type === "chart::Bar::SW") {
    new chartBarSW({ id, data: data.data });
  } else if (type === "chart::Line::SW") {
    new chartLineSW({ id, data: data.data });
  } else if (type === "chart::BarLine::SW") {
    new chartBarLineSW({ id, data: data.data });
  }
};
